package event

import "github.com/AsynkronIT/protoactor-go/actor"

type ID = uint16

type IEvent interface {
	Event()
	EventID() ID
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
type Handler func(iEvent IEvent, ctx actor.Context, args ...interface{})

type Dispatcher struct {
	handlers map[ID][]Handler
}

func NewDispatcher() *Dispatcher {
	return &Dispatcher{
		handlers: make(map[ID][]Handler),
	}
}

func (m *Dispatcher) Register(id ID, h Handler) {
	if handler, ok := m.handlers[id]; !ok {
		m.handlers[id] = []Handler{h}
	} else {
		m.handlers[id] = append(handler, h)
	}
}

func (m *Dispatcher) Dispatch(iEvent IEvent, ctx actor.Context, args ...interface{}) (err error) {
	handler, ok := m.handlers[iEvent.EventID()]
	if !ok {
		err = ErrNoHandler
		return
	}
	for _, h := range handler {
		h(iEvent, ctx, args...)
	}
	return
}
